package com.spring.arch.common.dto.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;

/**
 * 返回结果
 */
@ToString(callSuper = true)
@NoArgsConstructor
@Getter
@Setter
public class ResultDTO<T> extends AbstractResultDTO {
    private static final long serialVersionUID = -2726614537795789347L;

    /**
     * 结果数据
     */
    @ApiModelProperty(value = "结果数据", position = 10)
    @JsonProperty(index = 10)
    private T data;

    protected ResultDTO(final HttpStatus status) {
        super(status);
    }

    ///////////////////////////////////////
    // Builder
    ///////////////////////////////////////
    public static ResultDTO<Void> success() {
        return new ResultDTO<>(HttpStatus.OK);
    }

    public static ResultDTO<Void> failure(final String message) {
        final ResultDTO<Void> result = new ResultDTO<>(HttpStatus.BAD_REQUEST);
        result.setMessage(message);
        return result;
    }

    public static ResultDTO<Void> failure(final String message, final HttpStatus httpStatus) {
        final ResultDTO<Void> result = new ResultDTO<>(httpStatus);
        result.setMessage(message);
        return result;
    }

    public static ResultDTO<Void> failure(final ErrorDetailDTO... errorDetails) {
        final ResultDTO<Void> result = new ResultDTO<>(HttpStatus.BAD_REQUEST);
        result.setMessage("请求数据错误。");
        result.setErrorDetails(errorDetails);
        return result;
    }

    public static ResultDTO<Void> failure(final HttpStatus httpStatus, final String message, final ErrorDetailDTO... errorDetails) {
        final ResultDTO<Void> result = new ResultDTO<>(httpStatus);
        result.setMessage(message);
        result.setErrorDetails(errorDetails);
        return result;
    }

    public static <T> ResultDTO<T> success(final T data) {
        final ResultDTO<T> result = new ResultDTO<>(HttpStatus.OK);
        result.setData(data);
        return result;
    }

    /**
     * 扩展，增加失败返回异常消息、数据封装
     * @param data
     * @param message
     * @param <T>
     * @return
     */
    public static <T> ResultDTO<T> failure(final T data, String message) {
        final ResultDTO<T> result = new ResultDTO<>(HttpStatus.OK);
        result.setData(data);
        result.setMessage(message);
        return result;
    }

    public static <T> ResultDTO<T> failure(final T data, T message) {
        final ResultDTO<T> result = new ResultDTO<>(HttpStatus.OK);
        result.setData(data);
        result.setMessage(String.valueOf(message));
        return result;
    }
}
